using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using SuperMarketManagement.DAO.NHibernate;
using SuperMarketManagement.Entity;

namespace SuperMarketManagement.Web.Controllers
{
    public class SalesController : Controller
    {
        //
        // GET: /Sales/
        [Authorize(Roles = "admin,sale-manager,sale")]
        public ActionResult Index()
        {
            return View();
        }

        [Authorize(Roles = "admin,sale-manager,sale")]
        public ActionResult CreateInvoice()
        {
            DAOFactory factory = new DAOFactory();
            Invoice invoice;
            if (Request["uid"] == null)
            {
                invoice = new Invoice();
                invoice.CreatedDate = DateTime.Now;
                factory.InvoiceDAO.Save(invoice);
                factory.InvoiceDAO.Save(invoice);
                return RedirectToAction("CreateInvoice", new { uid = invoice.AutoId });
            }
            invoice = factory.InvoiceDAO.GetById(Convert.ToInt32(Request["uid"]));
            if (Request.RequestType.Equals("POST", StringComparison.OrdinalIgnoreCase))
            {
                if (Request["findCustomer"] != null)
                {
                    Session["customerKey"] = Request["customerKey"];
                    Session["suggestedCustomers"] = factory.CustomerDAO.FindByKeyword(Request["customerKey"]);
                }
                else if (Request["findProduct"] != null)
                {
                    Session["productKey"] = Request["productKey"];
                    Session["suggestedProducts"] = factory.ProductDAO.FindByKeyword(Request["productKey"]);
                }
                else if (Request["selectCustomer"] != null)
                {
                    SelectCustomer(invoice, factory);
                }
                else if (Request["insertProduct"] != null)
                {
                    InsertProduct(invoice, factory);
                }
                else if (Request["updateQuantity"] != null)
                {
                    UpdateQuantity(invoice, factory);
                }
                else if (Request["removeItem"] != null)
                {
                    RemoveInvoiceItem(invoice, factory);
                }
                else if (Request["cancelInvoice"] != null)
                {
                    factory.InvoiceDAO.Delete(invoice);
                    return RedirectToAction("Index");
                }
                else if (Request["saveInvoice"] != null)
                {
                    SaveInvoice(invoice, factory);
                    return RedirectToAction("PrintInvoice", new { uid = invoice.AutoId });
                }
            }
            //IList<Customer> suggestedCustomers = Session["suggestedCustomers"] as IList<Customer>;
            //IList<Product> suggestedProducts = Session["suggestedProducts"] as IList<Product>;

            return View(invoice);
        }

        [Authorize(Roles = "admin,sale-manager,sale,customer-manager")]
        public ActionResult PrintInvoice()
        {
            DAOFactory factory = new DAOFactory();
            Invoice invoice = factory.InvoiceDAO.GetById(Convert.ToInt32(Request["uid"]));

            return View(invoice);
        }

        private void SaveInvoice(Invoice invoice, DAOFactory factory)
        {
            foreach (var item in invoice.InvoiceItems)
            {
                SaveInvoiceItem(item, factory);
            }
        }

        private void SaveInvoiceItem(InvoiceItem item, DAOFactory factory)
        {
            double diff = item.Quantity;
            if (diff > 0)
            {
                IList<ProductBlock> blocks = factory.ProductBlockDAO.GetAvailablesByProductId(item.Product.AutoId);
                int index = blocks.Count - 1;
                while (diff > 0)
                {
                    ProductBlock block = blocks[index];
                    double s;
                    if (block.AvailableUnits >= diff)
                    {
                        s = diff;
                        diff = 0;
                    }
                    else
                    {
                        s = block.AvailableUnits;
                        diff = diff - s;
                    }
                    block.AvailableUnits = block.AvailableUnits - s;
                }
                factory.ProductBlockDAO.Save(blocks);
            }
        }

        private void RemoveInvoiceItem(Invoice invoice, DAOFactory factory)
        {
            long invoiceItemId = Convert.ToInt64(Request["removeInvoiceItemId"]);
            foreach (var item in invoice.InvoiceItems)
            {
                if (item.AutoId == invoiceItemId)
                {
                    invoice.RemoveInvoiceItem(item);
                    break;
                }
            }
            factory.InvoiceDAO.Save(invoice);
        }


        private void UpdateQuantity(Invoice invoice, DAOFactory factory)
        {
            foreach (var item in invoice.InvoiceItems)
            {
                string quantityKey = string.Format("iq_{0}", item.AutoId);
                item.Quantity = Convert.ToDouble(Request[quantityKey]);
            }
            factory.InvoiceDAO.Save(invoice);
        }

        private void SelectCustomer(Invoice invoice, DAOFactory factory)
        {
            invoice.Customer = factory.CustomerDAO.GetById(Convert.ToInt64(Request["customerId"]));
            factory.InvoiceDAO.Save(invoice);
            Session.Remove("suggestedCustomers");
        }

        private void InsertProduct(Invoice invoice, DAOFactory factory)
        {
            double quantity = Convert.ToDouble(Request["quantity"]);
            long productId = Convert.ToInt64(Request["productId"]);
            Product product = factory.ProductDAO.GetById(productId);
            var invoiceItems = invoice.InvoiceItems.Where(i => i.Product == product);
            if (invoiceItems.Count() == 1)
            {
                invoiceItems.First().Quantity += quantity;
            }
            else
            {
                InvoiceItem invoiceItem = new InvoiceItem(product, quantity, product.CurrentSellingPrice);
                invoice.AddInvoiceItem(invoiceItem);
            }
            factory.InvoiceDAO.Save(invoice);
        }
    }
}